import type {RouteRecordRaw} from "vue-router";
import {basicRouteMap} from "~/router/static-routes.ts";
import type {MenuData, MenuDataItem} from "~/layouts/basic-layout/MenuDataItem.ts";
import { omit } from 'lodash'
export const ROOT_ROUTE_REDIRECT_PATH = '/home'
const routerModules = import.meta.glob([
    '~/pages/**/*.vue',
    '!~/pages/**/*copy.vue',
    '!~/pages/**/component',
    '!~/pages/**/components',
    '!~/pages/**/composables',
    '!~/pages/**/hooks',
    '!~/pages/**/locales',
    '!~/pages/**/modules',
    '!~/pages/**/plugins',
    '!~/pages/**/tests',
    '!~/pages/**/test',
    '!~/pages/common',
])
/**
 * 请求后端的数据获取到的菜单的信息，默认数据是拉平的，需要对数据进行树结构的整理
 */
export function generateTreeRoutes(menus: MenuData) {
    const routeDataMap = new Map<string | number, RouteRecordRaw>()
    const menuDataMap = new Map<string | number, MenuDataItem>()
    for (const menuItem of menus) {
        if (!menuItem.id)
            continue
        const route = {
            path: menuItem.path,
            name: menuItem.name,
            component: getRouterModule(menuItem.component!),
            redirect: menuItem.redirect || undefined,
            meta: {
                title: menuItem?.title as string,
                icon: menuItem?.icon as string,
                keepAlive: menuItem?.keepAlive,
                id: menuItem?.id,
                parentId: menuItem?.parentId,
                affix: menuItem?.affix,
                parentKeys: menuItem?.parentKeys,
                url: menuItem?.url,
                hideInMenu: menuItem?.hideInMenu,
                hideChildrenInMenu: menuItem?.hideChildrenInMenu,
                hideInBreadcrumb: menuItem?.hideInBreadcrumb,
                target: menuItem?.target,
                locale: menuItem?.locale,
            },
        } as RouteRecordRaw
        const menu = formatMenu(route)
        routeDataMap.set(menuItem.id, route)
        menuDataMap.set(menuItem.id, menu)
    }
    const routeData: RouteRecordRaw[] = []
    const menuData: MenuData = []

    for (const menuItem of menus) {
        if (!menuItem.id)
            continue
        const currentRoute = routeDataMap.get(menuItem.id)
        const currentItem = menuDataMap.get(menuItem.id)
        if (!menuItem.parentId) {
            if (currentRoute && currentItem) {
                routeData.push(currentRoute)
                menuData.push(currentItem)
            }
        }
        else {
            const pRoute = routeDataMap.get(menuItem.parentId)
            const pItem = menuDataMap.get(menuItem.parentId)
            if (currentItem && currentRoute && pRoute && pItem) {
                if (pRoute.children && pItem.children) {
                    pRoute.children.push(currentRoute)
                    pItem.children.push(currentItem)
                }
                else {
                    pItem.children = [currentItem]
                    pRoute.children = [currentRoute]
                }
            }
        }
    }
    return {
        menuData,
        routeData,
    }
}

function formatMenu(route: RouteRecordRaw, path?: string) {
    return {
        id: route.meta?.id,
        parentId: route.meta?.parentId,
        title: () => renderTitle(route),
        icon: route.meta?.icon || '',
        path: path ?? route.path,
        hideInMenu: route.meta?.hideInMenu || false,
        parentKeys: route.meta?.parentKeys || [],
        hideInBreadcrumb: route.meta?.hideInBreadcrumb || false,
        hideChildrenInMenu: route.meta?.hideChildrenInMenu || false,
        locale: route.meta?.locale,
        keepAlive: route.meta?.keepAlive || false,
        name: route.name as string,
        url: route.meta?.url || '',
        target: route.meta?.target || '_blank',
    }
}

export function generateFlatRoutes(routes: RouteRecordRaw[]) {
    const flatRoutesList = flatRoutes(routes)
    // 拿到拉平后的路由，然后统一添加一个父级的路由,通过这层路由实现保活的功能
    const parentRoute: RouteRecordRaw = {
        path: '/',
        redirect: ROOT_ROUTE_REDIRECT_PATH,
        name: 'ROOT_EMPTY_PATH',
        // fix: https://github.com/antdv-pro/antdv-pro/issues/179
        // component: getRouterModule('RouteView'),
        children: flatRoutesList,
    }
    return [parentRoute]
}

// 路由拉平处理
function flatRoutes(routes: RouteRecordRaw[], parentName?: string, parentComps: RouteRecordRaw['component'][] = []) {
    const flatRouteData: RouteRecordRaw[] = []
    for (const route of routes) {
        const parentComponents = [...parentComps]
        const currentRoute = omit(route, ['children']) as RouteRecordRaw
        if (!currentRoute.meta)
            currentRoute.meta = {}
        if (parentName)
            currentRoute.meta.parentName = parentName
        if (parentComponents.length > 0)
            currentRoute.meta.parentComps = parentComponents
        currentRoute.meta.originPath = currentRoute.path
        flatRouteData.push(currentRoute)
        if (route.children && route.children.length) {
            const comp = checkComponent(route.component)
            if (comp)
                parentComponents.push(comp)
            flatRouteData.push(...flatRoutes(route.children, route.name as string, [...parentComponents]))
        }
    }
    return flatRouteData
}

function checkComponent(component: RouteRecordRaw['component']) {
    for (const componentKey in basicRouteMap) {
        if (component === (basicRouteMap as any)[componentKey])
            return undefined
    }
    return component
}

export function getRouterModule(path?: string): any {
    if (!path)
        return basicRouteMap.ComponentError
    // 判断是否在basicRouteMap中存在
    if (path in basicRouteMap)
        return (basicRouteMap as any)[path]

    // 判断开头是不是/
    if (path.startsWith('/'))
        path = path.slice(1)
    // 组装数据格式
    const fullPath = `/src/pages/${path}.vue`
    const fullPathIndex = `/src/pages/${path}/index.vue`
    if (fullPathIndex in routerModules)
        return checkEager(routerModules[fullPathIndex])
    // 返回插件信息
    return checkEager(routerModules[fullPath])
}

function checkEager(module: any) {
    if (typeof module === 'object' && 'default' in module)
        return module.default

    return module
}
function renderTitle(route: RouteRecordRaw) {
    const { title, locale } = route.meta || {}
    if (!title)
        return ''
    return title
}
